#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void perceptron_update_history(unsigned long long int *hist,int hist_size,int taken);
int perceptron_predict(unsigned long long int hist,int hist_size,int weights[]);
void perceptron_update(unsigned long long int *hist, int hist_size,int weights[],int y_out,int taken);
void print_weights(int *weights,int num);
void print_history(unsigned long long int hist);

int main()
{
	
//	unsigned long long int history = 0;
	unsigned long long int history = 0x5555555555555555ULL;
	int i, hist_size;
	int *weights,taken=0,y,i;

	printf("Enter history size:");
	scanf("%d",&hist_size);
	
	weights = malloc(sizeof(int) * (hist_size+1));
	memset(weights,0,sizeof(int)*(hist_size+1));
	weights[0] = 1;
	
<<<<<<< .mine
	for(i=1;1;i++)
=======
	for (i=0; i < 1000; i++)
>>>>>>> .r11
	{
		int n = i % hist_size;
		y = perceptron_predict(history,hist_size,weights);		
<<<<<<< .mine
		printf("%d****",i);
		
//		taken = !taken;

		printf("y_out = %d\ntaken = %d\n",y,taken);
		print_weights(weights,hist_size+1);
		printf("");
		taken = 1;
//		taken = 0;
//		taken = rand() % 2;
=======
		taken = sign(rand() % 2);
		printf("y:%d taken:%d\n", y, taken);
>>>>>>> .r11
		perceptron_update(&history,hist_size,weights,y,taken);		
		history = 0x5555555555555555ULL;
		print_history(history);
		fflush(stdin);
	}
}

<<<<<<< .mine
void perceptron_update_history(unsigned long long int *hist,int hist_size,int taken)
=======
int sign(int y)
{
	return y > 0 ? 1 : -1;
}

void perceptron_update_history(unsigned long int *hist,int hist_size,int taken)
>>>>>>> .r11
{
	unsigned long long int btaken = taken?1ULL:0ULL;

	*hist = ((*hist << 1) | btaken);	
}

int perceptron_predict(unsigned long long int hist,int hist_size,int weights[])
{
	int y = weights[0],i,scale;
	unsigned long long int mask = 1;

	for(i=1; i<=hist_size; i++)
	{
		scale = hist & mask;
		y += weights[i] * sign(scale);
		mask = mask << 1;
	}

	return y;	
}

<<<<<<< .mine
void perceptron_update(unsigned long long int *hist, int hist_size,int weights[],int y_out,int taken)
=======
void perceptron_update(unsigned long int *hist, 
			int hist_size,
			int weights[],
			int y_out,
			int taken)
>>>>>>> .r11
{
	
	int i,scale_hist;
	unsigned long long int mask =1;
	static int theta;

	theta  = (int)(1.93*(double)hist_size+14.0);
	int theta = 1.93 * hist_size + 14;

<<<<<<< .mine
	if( !(y_out < 0 && taken || y_out >= 0 && !taken || abs(y_out) <= theta ) )
	{
		perceptron_update_history(hist,hist_size,taken);
		return;
	}

	weights[0] += scale_taken;	

	for(i=1;i<=hist_size+1;i++)
=======
	if (sign(y_out) != taken || abs(y_out) <= theta)
>>>>>>> .r11
	{
		printf("updating weights\n");
		for(i=0; i <= hist_size; i++)
		{
                	scale_hist = sign(*hist & mask);	
			weights[i] += taken * scale_hist;
			mask = mask << 1;
		}
	}

	perceptron_update_history(hist,hist_size,taken);
}
<<<<<<< .mine

void print_weights(int *weights,int num)
{
	int i=0;
	
	for(i=0;i<num;i++)
	{
		printf("w[%d]=%d ",i,weights[i]);
	}

	printf("\n");
}

void print_history(unsigned long long int hist)
{
	int i;
	unsigned long long int mask = 1ULL << 63;

	for(i=0;i<64;i++)
	{
		printf("%d",(hist & mask)? 1:0);
		mask = mask >> 1;
	}
	printf("\n");
}
=======
>>>>>>> .r11
